package com.itheima.reggie.service.impl;

import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.common.BaseContext;
import com.itheima.reggie.dto.OrdersDto;
import com.itheima.reggie.entity.*;
import com.itheima.reggie.mapper.OrdersMapper;
import com.itheima.reggie.service.AddressBookService;
import com.itheima.reggie.service.OrderDetailService;
import com.itheima.reggie.service.OrdersService;
import com.itheima.reggie.service.ShoppingCartService;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.datetime.DateFormatter;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements OrdersService {

    @Autowired
    private OrdersMapper ordersMapper;

    @Autowired
    private AddressBookService addressBookService;

    @Autowired
    private ShoppingCartService shoppingCartService;

    @Autowired
    private OrderDetailService orderDetailService;


    @Override
    public void saveWithDetail(Orders orders) {

        Long currentId = BaseContext.getCurrentId();

        LambdaQueryWrapper<AddressBook> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AddressBook::getUserId,currentId);
        wrapper.eq(AddressBook::getId,orders.getAddressBookId());
        AddressBook addressBook = addressBookService.getOne(wrapper);
        OrdersDto ordersDto = new OrdersDto();


        //设置订单状态
        //订单状态 1待付款，2待派送，3已派送，4已完成，5已取消
        orders.setStatus(2);

        orders.setUserId(currentId);

        //设置点击支付下单时间
        orders.setCheckoutTime(LocalDateTime.now());


        QueryWrapper<ShoppingCart> wrapper1 = new QueryWrapper<>();
        wrapper1.select("sum(amount*number) as 'total',sum(number) as number,user_id")
                .eq("user_id",currentId)
                .groupBy("user_id");
        Map<String, Object> map = shoppingCartService.getMap(wrapper1);

        BigDecimal total =(BigDecimal) map.get("total");
        Object number = map.get("number");
        orders.setAmount(total);
        orders.setNumber(String.valueOf(number));

        orders.setOrderTime(LocalDateTime.now());
//        this.save(orders);

        BeanUtils.copyProperties(orders,ordersDto);

        //设置地址
        ordersDto.setAddress(addressBook.getDetail());

        //电话
        ordersDto.setPhone(addressBook.getPhone());

        //设置收货人
        ordersDto.setConsignee(addressBook.getConsignee());

        this.save(ordersDto);


        LambdaQueryWrapper<ShoppingCart> wrapper2 = new LambdaQueryWrapper<>();
        wrapper2.eq(ShoppingCart::getUserId,currentId);
        List<ShoppingCart> list = shoppingCartService.list(wrapper2);
        List<OrderDetail> detailList = list.stream().map(item->{
            OrderDetail detail = new OrderDetail();
            detail.setOrderId(ordersDto.getId());
            detail.setNumber(item.getNumber());
            detail.setAmount(item.getAmount());
            detail.setName(item.getName());
            detail.setImage(item.getImage());
            Long dishId = item.getDishId();
            if(dishId!=null){
                detail.setDishId(dishId);
            }else{
                detail.setSetmealId(item.getSetmealId());
            }
            detail.setDishFlavor(item.getDishFlavor());
            return detail;
        }).collect(Collectors.toList());

        orderDetailService.saveBatch(detailList);

        //下单后删除购物车数据
        LambdaQueryWrapper<ShoppingCart> wrapper3 = new LambdaQueryWrapper<>();
        wrapper3.eq(ShoppingCart::getUserId,currentId);
        shoppingCartService.remove(wrapper3);
    }

    @Override
    public void excelExport(HttpServletResponse response) throws IOException {
        List<Orders> list = ordersMapper.selectList(null);
        List<OrderInfo> res = list.stream().map(item -> {
            OrderInfo orderInfo = new OrderInfo();

            orderInfo.setOrderId(String.valueOf(item.getId()));

            Integer status = item.getStatus();
            String ret = status==1?"待付款":status==2?"待派送":status==3?"已派送":"已完成";
            orderInfo.setStatus(ret);

            orderInfo.setUserName(item.getUserName());
            orderInfo.setPhone(item.getPhone());
            orderInfo.setAddress(item.getAddress());

            DateTimeFormatter pattern = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm");
            orderInfo.setCheckoutTime(item.getCheckoutTime().format(pattern));

            orderInfo.setAmount("￥"+item.getAmount());

            return orderInfo;
        }).collect(Collectors.toList());
        System.out.println(res);
        String fileName = "订单明细";
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition", "attachment;filename=" + new String( fileName.getBytes("gb2312"), "ISO8859-1" ) + ".xlsx");
        ServletOutputStream out = response.getOutputStream();
        ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX,true);
        Sheet sheet = new Sheet(1,0, OrderInfo.class);

        //设置自适应宽度
        sheet.setAutoWidth(Boolean.TRUE);
        sheet.setSheetName("订单明细");
        writer.write(res,sheet);
        writer.finish();
        out.flush();
        response.getOutputStream().close();
        out.close();
    }
}
